package com.gnerv.cms.listener.permission;

import com.gnerv.cms.dto.PermissionSaveDTO;
import com.gnerv.cms.service.IPermissionService;
import com.google.common.collect.Lists;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

@Component
public class PermissionAutoStatisticsListener implements ApplicationListener<ContextRefreshedEvent> {

    @Resource
    private IPermissionService permissionService;

    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        savePermission(contextRefreshedEvent);
    }

    public void savePermission(ContextRefreshedEvent contextRefreshedEvent){
        List<PermissionSaveDTO> permissionSaveDTOS = Lists.newArrayListWithCapacity(50);
        Map<String, Object> beans = contextRefreshedEvent.getApplicationContext().getBeansWithAnnotation(RestController.class);
        for (Map.Entry<String, Object> stringObjectEntry : beans.entrySet()) {
            Class<?> clazz = stringObjectEntry.getValue().getClass();
            RequestMapping annotation = AnnotationUtils.findAnnotation(clazz, RequestMapping.class);
            String parentUrl = annotation.value()[0];
            Method[] methods = clazz.getMethods();
            for (Method declaredMethod : methods) {
                PermissionSaveDTO permissionSaveDTO = new PermissionSaveDTO();
                permissionSaveDTO.setStatus(1);
                RequestMapping requestMapping = AnnotationUtils.findAnnotation(declaredMethod, RequestMapping.class);
                if(ObjectUtils.isEmpty(requestMapping)){
                    continue;
                }
                String url = requestMapping.value()[0];
                permissionSaveDTO.setName(requestMapping.name());
                permissionSaveDTO.setSummary(requestMapping.name());
                permissionSaveDTO.setUrl(parentUrl + url);
                RequiresPermissions requiresPermissions = AnnotationUtils.getAnnotation(declaredMethod, RequiresPermissions.class);
                if(ObjectUtils.isEmpty(requiresPermissions)){
                    permissionSaveDTO.setValue("");
                }else {
                    String permission = requiresPermissions.value()[0];
                    permissionSaveDTO.setValue(permission);
                }
                permissionSaveDTOS.add(permissionSaveDTO);
            }
        }
        permissionService.initSavePermission(permissionSaveDTOS);
    }

}